//#define _YaRRDebug 1


/************************************** Polite Request ***************************************
** I have put a lot of time and effort into YaRR. If you want to use some of the source     **
** please tell me. Anything used from YaRR must be open source, as is scripts.dll.          **
***************************************** Thank you *****************************************/


#define YARR_VERSION "0.7.0"
#define _WIN32_WINNT 0x0400

#include <Winsock2.h>
#include <windows.h>
#include <new>
#include "time.h"

#include "stdio.h"
#include "stdlib.h"

#include "sqlite3.h"

#include "scripts.h"
#include "engine.h"
#include "plugin.h"
#include "gmmain.h"

#define M_PI 3.14159265358979323846


class ScopeLog
{

	static FILE *f;
	static int level;
	static int ref;
	static DWORD thread;

	char name[256];
	int line;
public:
	ScopeLog(const char *Name, int Line)
	{
		if(!f || GetCurrentThreadId() != thread)
		{
			return;
		}
		if(strcmp(Name, "Global") == 0)
		{
			thread = GetCurrentThreadId();
		}
		strcpy(name, Name);
		line = Line;
		if(!f)
		{	
			char basepath[256];
			GetCurrentDirectory(64, basepath);
			strcat(basepath, "\\log\\");

			char buffer[128];
			time_t t = time(0);
			strftime(buffer, 128, "Scope-%d-%m-%Y.txt", gmtime(&t));

			strcat(basepath, buffer);
			printf("%s\n", basepath);
			f = fopen(basepath, "w");
			if(!f)
			{
				printf("could not create file\n");
			}
			
		}	
		
		for(int i = 0; i < level; i++)
		{
			fputc('-', f);
		}

		fprintf(f, "Enter:%d:%s\n", Line, Name);
		level++;
		ref++;

	}

	~ScopeLog()
	{
		if(!f || GetCurrentThreadId() != thread)
		{
			return;
		}
		ref--;
		level--;
		for(int i = 0; i < level; i++)
		{
			fputc('-', f);
		}

		fprintf(f, "Leave:%d:%s\n", line, name);

		if(ref == 0)
		{
			fclose(f);
			f = 0;
		}
		
	}
};
#ifdef _YaRRDebug
#define DLOG ScopeLog dlog(__FUNCTION__, __LINE__)
#else
#define DLOG
#endif

template <class T> class Stacker;
#define IterateStack(Var, Type, Stack) Type Var; \
	Stack->Reset(); \
	while(Stack->Iterate(&Var))


#define DLLEXPORT __declspec(dllexport)
#pragma warning(disable: 4996 4345 4127)


#include "YaRRMemory.h"

template <class T> class Stacker
{
	T *Data;
	int Position;
	int Size;
public:
	Stacker()
	{
		DLOG;
		Data = 0;
		Position = 0;
		Size = 0;
	}
	~Stacker()
	{
		DLOG;
		if(Data)
		{
			CDealloc((void *)Data);
		}
	}

	int Push(const T Item)
	{
		DLOG;
		if(!Data)
		{
			Data = (T *)CAlloc(sizeof(T)*1);
			Size = 1;
			Data[0] = Item;
			return 1;
		}
		Size++;
		Data = (T *)RAlloc((void *)Data, sizeof(T)*Size);
		Data[Size-1] = Item;
		return Size;
				
	}

	T Pop()
	{
		DLOG;
		if(!Data || Size == 0)
		{
			return 0;
		}

		Size--;
		T item = Data[Size];
		Data = (T *)RAlloc((void *)Data, sizeof(T)*Size);
		return item;
	}

	bool Pop(T *Item)
	{
		DLOG;
		if(!Data)
		{
			return 0;
		}

		Size--;
		(*Item) = Data[Size];
		Data = (T *)RAlloc((void *)Data, sizeof(T)*Size);
		return 1;
	}

	bool Iterate(T **Item)
	{
		DLOG;
		if(!Data)
		{
			return 0;
		}
		if(Position >= Size)
		{
			return 0;
		}

		(*Item) = &Data[Position];
		Position++;
		return 1;
	}

	bool Iterate(T *Item)
	{
		DLOG;
		if(!Data)
		{
			return 0;
		}
		if(Position >= Size)
		{
			return 0;
		}

		(*Item) = Data[Position];
		Position++;
		return 1;
	}

	T *Iterate()
	{
		DLOG;
		if(!Data)
		{
			return 0;
		}
		if(Position >= Size)
		{
			return 0;
		}

		Position++;
		return &Data[Position-1];
	}

	void Reset()
	{
		DLOG;
		Position = 0;
	}

	const T operator [](int Pos)
	{
		DLOG;
		return Data[Pos];
	}

	const T *At(int Pos)
	{
		if(!Data)
		{
			return 0;
		}
		if(Pos >= Size)
		{
			return 0;
		}
		return &Data[Pos];
	}

	void Erase(int Pos)
	{
		DLOG;
		if(Pos >= Size)
		{
			return;
		}		
		for(int i = Pos; i < Size; i++)
		{
			Data[i] = Data[i+1];
		}
		
		Size--;
		Data = (T *)RAlloc((void *)Data, sizeof(T)*Size);
	}

	void Insert(int Pos, T Item)
	{
		DLOG;
		if((Pos >= Size) || !Data)
		{
			this->Push(Item);
			return;
		}

		if(Pos < 0)
		{
			this->Insert(0, Item);
			return;
		}

		Size++;
		Data = (T *)RAlloc((void *)Data, sizeof(T)*Size);
		for(int i = Size; i >= Pos; i--)
		{
			Data[i] = Data[i-1];
		}
		Data[Pos] = Item;
	}

	void Clear()
	{
		DLOG;
		if(Data)
		{
			CDealloc((void *)Data);
		}
		Data = 0;
		Position = 0;
		Size = 0;
	}
	
	const int Length()
	{
		DLOG;
		return Size;
	}

	bool Empty()
	{
		DLOG;
		if(Data)
		{
			return 0;
		}
		else
		{
			return 1;
		}
	}

	void Edit(int At, T &item)
	{
		if(!Data)
		{
			return;
		}
		if(At >= Size)
		{
			return;
		}
		Data[At] = item;
	}
};

namespace Colour
{
	struct CRGB
	{
		int R;
		int G;
		int B;
	};
};
class RankInfo
{
public:
	static float Player_Damage_CoEfficient;
	static float Vehicle_Damage_CoEfficient;
	static float Building_Damage_CoEfficient;
	static float Beacon_Damage_CoEfficient;
	static float C4_Damage_CoEfficient;
	
	static float Player_Repair_CoEfficient;
	static float Vehicle_Repair_CoEfficient;
	static float Building_Repair_CoEfficient;

	float Player_Damage;		//not raw damage, YaRR will do some fiddling with it. 
	float Vehicle_Damage;	
	float Building_Damage;
	float Beacon_Damage;
	float C4_Damage;

	float Player_Repair;		//same as above
	float Vehicle_Repair;
	float Building_Repair;

	int Player_Kills;			//Not kills IE: killing blow, YaRR will increment this everytime Player_Damage goes over a certain threshold
	int Vehicle_Kills;	
	int LightVehicle_Kills;	
	int HeavyVehicle_Kills;	
	int Building_Kills;
	int Beacon_Kills;
	int C4_Kills;
	int Players_Repaired;		//same as above
	int Vehicles_Repaired;
	int Buildings_Repaired;

	int BeaconAttempts;			//Beacons planted in the enemy base(doesn't have to be right next to a building)
	int BeaconCover;			//Time spent with an offencive character or vehicle in close proximity to a beacon
	int TimeAFK;				//You are classed as AFK after 20 seconds of doing no action. You will be severly punished for having a high number for this.

	int VetScore;				//Total vet score (note this is nothing to do with the ranks)
	int Level;					//Player level is worked out as it increments, not needed but makes life easier.
	float RankScore;				//Score that contributes to the rank

	int Killer_Medals;
	int ArmsDestroyer_Medals;
	int ArmorDestroyer_Medals;
	int Demolition_Medals;
	int Sabatage_Medals;
	int BeaconSniffer_Medals;


	int Killer_Awards;
	int ArmsDestroyer_Awards;
	int ArmorDestroyer_Awards;
	int Demolition_Awards;
	int Sabatage_Awards;
	int BeaconSniffer_Awards;
	int Medals_Awards;
};


struct Player
{
	int ID;
	int Points;
	char Nick[40];
	cPlayer *data;
	int HeadShots;

	float BHS;
	bool Muted;
	char Access;
	char IRCNick[64];

	bool BlockBeacons;
	bool BlockCharacters;
	bool BlockVehicles;
	bool Spectating;
	bool Shunned;
	Colour::CRGB PPageColour;
	char PPageSound[64];
	char Node[128];
	RankInfo Rank;

	bool Rooted;
	bool Protected;
};


#include "YaRRFunctions.h"
#include "YaRRPlayers.h"
#include "YaRRCrates.h"
#include "YaRRSettings.h"
#include "YaRRIRC.h"
#include "YaRRDB.h"
#include "YaRRStrings.h"
#include "YaRRWorker.h"
#include "YaRRGlobal.h"

class YaRRLink : public YaRRDatabase, public YaRRMemory, public YaRRPlayers, public IRC, public YaRRSettings, public YaRRStrings, public YaRRGlobal
{

};

#include "YaRRScripts.h"
#include "YaRRHooking.h"
#include "YaRRCommands.h"
#include "YaRRphp.h"
#include "YaRRTrace.h"
#include "YaRRVeteran.h"